#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
int N;
int attack[302][302];
bool used[302][302];
int dxdy[][5] = {
    {0, 0, -1, 1, 0},
    {1, -1, 0, 0, 0}
};

bool valid(int x, int y) {
    return x >= 0 && y >= 0;
} 


void solve();

int main() {
    ios::sync_with_stdio(false);
    cin >> N;
    memset(attack, -1, sizeof attack);
    for (int i = 0; i < N; i++) {
        int xi, yi, ti;
        cin >> xi >> yi >> ti;
        for (int i = 0; i < 5; i++) {
            int nx = xi + dxdy[0][i];
            int ny = yi + dxdy[1][i];
            if (valid(nx, ny)) {
                if (attack[nx][ny] == -1) attack[nx][ny] = ti;
                attack[nx][ny] = min(attack[nx][ny], ti);
            }
        }
    }
    solve();
}

struct Ship {
    pair<int, int> pos;
    int time;
    Ship(int _x, int _y, int _time): pos(_x, _y), time(_time) {}
};


bool go(int x, int y, int t) {
    if (attack[x][y] == -1) return true;
    if (attack[x][y] > t) return true;
    return false;
}

void solve() {
    queue<Ship> q;
    q.emplace(0, 0, 0);
    used[0][0] = true;
    while (!q.empty()) {
        Ship t = q.front(); q.pop();
        if (attack[t.pos.first][t.pos.second] == -1) {
            cout << t.time << endl;
            return;
        }

        for (int i = 0; i < 4; i++) {
            int nx = t.pos.first + dxdy[0][i];
            int ny = t.pos.second + dxdy[1][i];
            int nt = t.time + 1;
            if (valid(nx, ny) && go(nx, ny, nt) && !used[nx][ny]) {
                q.emplace(nx, ny, nt);
                used[nx][ny] = true;
            }
        }

    }
    cout << -1 << endl;
}